export default codemirror => {
	;(function(mod) {
		mod(codemirror)
	})(function(CodeMirror) {
		CodeMirror.defineOption('placeholder', '', function(cm, val, old) {
			var prev = old && old !== CodeMirror.Init
			if (val && !prev) {
				cm.on('blur', onBlur)
				cm.on('change', onChange)
				cm.on('swapDoc', onChange)
				onChange(cm)
			} else if (!val && prev) {
				cm.off('blur', onBlur)
				cm.off('change', onChange)
				cm.off('swapDoc', onChange)
				clearPlaceholder(cm)
				var wrapper = cm.getWrapperElement()
				wrapper.className = wrapper.className.replace(' CodeMirror-empty', '')
			}

			if (val && !cm.hasFocus()) onBlur(cm)
		})

		function clearPlaceholder(cm) {
			if (cm.state.placeholder) {
				cm.state.placeholder.parentNode.removeChild(cm.state.placeholder)
				cm.state.placeholder = null
			}
		}
		function setPlaceholder(cm) {
			clearPlaceholder(cm)
			var elt = (cm.state.placeholder = document.createElement('pre'))
			elt.style.cssText = 'height: 0; overflow: visible; color: #80848f;'
			elt.style.direction = cm.getOption('direction')
			elt.className = 'CodeMirror-placeholder'
			var placeHolder = cm.getOption('placeholder')
			if (typeof placeHolder === 'string') placeHolder = document.createTextNode(placeHolder)
			elt.appendChild(placeHolder)
			cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild)
		}

		function onBlur(cm) {
			if (isEmpty(cm)) setPlaceholder(cm)
		}
		function onChange(cm) {
			let wrapper = cm.getWrapperElement()
			let empty = isEmpty(cm)
			wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + (empty ? ' CodeMirror-empty' : '')

			if (empty) setPlaceholder(cm)
			else clearPlaceholder(cm)
		}

		function isEmpty(cm) {
			return cm.lineCount() === 1 && cm.getLine(0) === ''
		}
	})
}
